/*
 * All method in this Class is static method
 * and this Class have one only default Constructor.
 * 
 * WADSUtil use to manage wads xml data store file.
 */

package wads.com;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import sandbox.org.wads.elements.*;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.enhydra.jawe.JaWEManager;
import org.enhydra.shark.xpdl.elements.PackageHeader;
import org.enhydra.shark.xpdl.elements.WorkflowProcesses;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;

/**
 *
 * @author Nattasan W.
 */
public class WADSUtil {
  
  public static final String RES_URL = "http://localhost:8084/WADSWeb/";
 
  public static Wads fromXML(String wadsurl) {
    try {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder loader = factory.newDocumentBuilder();
      Document document = loader.parse(wadsurl);
      Element wads = document.getDocumentElement();
      Wads refWads = new Wads();
      refWads.setReadOnly(false);
      
      if(wads.getNodeName().equals("Wads")) {
        for(int i=0;i<wads.getChildNodes().getLength();i++) {
          if(wads.getChildNodes().item(i).getNodeName().equals("WadsHeader")) {
            WadsHeader refWadsHeader = new WadsHeader(refWads);
            Node wadsheader = wads.getChildNodes().item(i);
            for(int j=0;j<wadsheader.getChildNodes().getLength();j++) {
              if(wadsheader.getChildNodes().item(j).getNodeName().equals("Requester")) {
                refWadsHeader.setRequester(wadsheader.getChildNodes().item(j).getTextContent());
                System.out.println("Item found: "+wadsheader.getChildNodes().item(j).getTextContent());
              }
              if(wadsheader.getChildNodes().item(j).getNodeName().equals("Created")) {
                refWadsHeader.setCreated(wadsheader.getChildNodes().item(j).getTextContent());
                System.out.println("Item found: "+wadsheader.getChildNodes().item(j).getTextContent());
              }
              if(wadsheader.getChildNodes().item(j).getNodeName().equals("Description")) {
                refWadsHeader.setDescription(wadsheader.getChildNodes().item(j).getTextContent());
                System.out.println("Item found: "+wadsheader.getChildNodes().item(j).getTextContent());
              }
            }
          }
          
          if(wads.getChildNodes().item(i).getNodeName().equals("RequestDetails")) {
            RequestDetails refRqDetails = new RequestDetails(refWads);
            Node requestdetails = wads.getChildNodes().item(i);
            for(int k=0;k<requestdetails.getChildNodes().getLength();k++) {
              if(requestdetails.getChildNodes().item(k).getNodeName().equals("Archetype")) {
                Archetype refArchetype = new Archetype(refRqDetails);
                Node arch = requestdetails.getChildNodes().item(k);
                for(int a=0;a<arch.getAttributes().getLength();a++) {
                  if(arch.getAttributes().item(a).getNodeName().equals("Id")) {
                    refArchetype.setId(arch.getAttributes().item(a).getNodeValue());
                  }
                  if(arch.getAttributes().item(a).getNodeName().equals("Name")) {
                    refArchetype.setName(arch.getAttributes().item(a).getNodeValue());
                  }
                  if(arch.getAttributes().item(a).getNodeName().equals("Path")) {
                    refArchetype.setPath(arch.getAttributes().item(a).getNodeValue());
                  }
                }
              }
              if(requestdetails.getChildNodes().item(k).getNodeName().equals("CurrentActivity")) {
                CurrentActivity refCurAct = new CurrentActivity(refRqDetails);
                refCurAct.setValue(requestdetails.getChildNodes().item(k).getTextContent());
                System.out.println("Item found: "+requestdetails.getChildNodes().item(k).getTextContent());
              }
              if(requestdetails.getChildNodes().item(k).getNodeName().equals("DataFields")) {
                DataFields refDataFields = new DataFields(refRqDetails);
                Node datafields = requestdetails.getChildNodes().item(k);
                //for(int l=0;l<datafields.getChildNodes().getLength();l++) {
                  //DataField refDataField = new DataField(refDataFields);
                  //Node datafElem = datafields.getChildNodes().item(l);
                  NodeList dataf = document.getElementsByTagName("DataField");
                  for(int a=0;a<dataf.getLength();a++) {
                    DataField refDataField = new DataField(refDataFields);
                    for(int b=0;b<dataf.item(a).getAttributes().getLength();b++) {
                      if(dataf.item(a).getAttributes().item(b).getNodeName().equals("Id")) {
                        refDataField.setId(dataf.item(a).getAttributes().item(b).getNodeValue());
                        System.out.println("Item found: "+dataf.item(a).getAttributes().item(b));
                      }
                      if(dataf.item(a).getAttributes().item(b).getNodeName().equals("Name")) {
                        refDataField.setName(dataf.item(a).getAttributes().item(b).getNodeValue());
                        System.out.println("Item found: "+dataf.item(a).getAttributes().item(b));
                      }
                      if(dataf.item(a).getAttributes().item(b).getNodeName().equals("Val")) {
                        refDataField.setVal(dataf.item(a).getAttributes().item(b).getNodeValue());
                        System.out.println("Item found: "+dataf.item(a).getAttributes().item(b));
                      }
                    }
                  }
//                  for(int a=0;a<datafElem.getAttributes().getLength();a++) {
//                    if(datafElem.getAttributes().item(a).getNodeName().equals("Id")) {
//                      refDataField.setId(datafElem.getAttributes().item(a).getNodeValue());
//                      System.out.println(datafElem.getAttributes().item(a).getNodeValue());
//                    }
//                    if(datafElem.getAttributes().item(a).getNodeName().equals("Name")) {
//                      refDataField.setName(datafElem.getAttributes().item(a).getNodeValue());
//                      System.out.println(datafElem.getAttributes().item(a).getNodeValue());
//                    }
//                    if(datafElem.getAttributes().item(a).getNodeName().equals("Val")) {
//                      refDataField.setVal(datafElem.getAttributes().item(a).getNodeValue());
//                      System.out.println(datafElem.getAttributes().item(a).getNodeValue());
//                    }
//                  }
//                }
              }
            }
          }
          
          if(wads.getChildNodes().item(i).getNodeName().equals("Approvals")) {
            Approvals refApprovals = new Approvals(refWads);
            NodeList approval = document.getElementsByTagName("Approval");
            for(int a=0;a<approval.getLength();a++) {
              Approval refApproval = new Approval(refApprovals);
              for(int b=0;b<approval.item(a).getChildNodes().getLength();b++) {
                if(approval.item(a).getChildNodes().item(b).getNodeName().equals("ActivityId")) {
                  refApproval.setActivityId(approval.item(a).getChildNodes().item(b).getTextContent());
                  System.out.println("Item found: "+approval.item(a).getChildNodes().item(b).getTextContent());
                }
                if(approval.item(a).getChildNodes().item(b).getNodeName().equals("Approver")) {
                  refApproval.setApprover(approval.item(a).getChildNodes().item(b).getTextContent());
                  System.out.println("Item found: "+approval.item(a).getChildNodes().item(b).getTextContent());
                }
                if(approval.item(a).getChildNodes().item(b).getNodeName().equals("Created")) {
                  refApproval.setCreated(approval.item(a).getChildNodes().item(b).getTextContent());
                  System.out.println("Item found: "+approval.item(a).getChildNodes().item(b).getTextContent());
                }
                if(approval.item(a).getChildNodes().item(b).getNodeName().equals("Replied")) {
                  refApproval.setReplied(approval.item(a).getChildNodes().item(b).getTextContent());
                  System.out.println("Item found: "+approval.item(a).getChildNodes().item(b).getTextContent());
                }
                if(approval.item(a).getChildNodes().item(b).getNodeName().equals("Message")) {
                  refApproval.setMessage(approval.item(a).getChildNodes().item(b).getTextContent());
                  System.out.println("Item found: "+approval.item(a).getChildNodes().item(b).getTextContent());
                }
              }
            }
//            Node approvals = wads.getChildNodes().item(i);
//            for(int m=0;m<approvals.getChildNodes().getLength();m++) {
//              Approval refApproval = new Approval(refApprovals);
//              Node approval = approvals.getChildNodes().item(m);
//              refApproval.setId(approval.getAttributes().item(0).getNodeValue());
//              for(int n=0;n<approvals.getChildNodes().item(m).getChildNodes().getLength();n++) {
//                if(approvals.getChildNodes().item(m).getChildNodes().item(n).getNodeName().equals("ActivityId")) {
//                  refApproval.setActivityId(approvals.getChildNodes().item(m).getChildNodes().item(n).getNodeValue());
//                }
//                if(approvals.getChildNodes().item(m).getChildNodes().item(n).getNodeName().equals("Approver")) {
//                  refApproval.setApprover(approvals.getChildNodes().item(m).getChildNodes().item(n).getNodeValue());
//                }
//                if(approvals.getChildNodes().item(m).getChildNodes().item(n).getNodeName().equals("Created")) {
//                  refApproval.setCreated(approvals.getChildNodes().item(m).getChildNodes().item(n).getNodeValue());
//                }
//                if(approvals.getChildNodes().item(m).getChildNodes().item(n).getNodeName().equals("Replied")) {
//                  refApproval.setReplied(approvals.getChildNodes().item(m).getChildNodes().item(n).getNodeValue());
//                }
//                if(approvals.getChildNodes().item(m).getChildNodes().item(n).getNodeName().equals("Message")) {
//                  refApproval.setMessage(approvals.getChildNodes().item(m).getChildNodes().item(n).getNodeValue());
//                }
//              }
//            }
          }
        }
      }
      
      return refWads;
      
    } catch (SAXException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ParserConfigurationException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    }
    
    return null;
  }
  
  public static void toXML(Wads wads, File wadsfile) {
    try {
      DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
      DocumentBuilder builder = factory.newDocumentBuilder();
      Document wadsDoc = builder.newDocument();
      
      Element root = wadsDoc.createElement(Wads.class.getSimpleName());
      wadsDoc.appendChild(root);
      
      Element wadsheader = wadsDoc.createElement(WadsHeader.class.getSimpleName());
      root.appendChild(wadsheader);
      Element requestdetails = wadsDoc.createElement(RequestDetails.class.getSimpleName());
      root.appendChild(requestdetails);
      Element approvals = wadsDoc.createElement(Approvals.class.getSimpleName());
      root.appendChild(approvals);
      
      wadsheader.appendChild(wadsDoc.createElement(Requester.class.getSimpleName()).appendChild(wadsDoc.createTextNode(wads.getWadsHeader().getRequester())));
      System.out.println("AAAA"+wads.getWadsHeader().getRequester()+"BBBB");
      wadsheader.appendChild(wadsDoc.createElement(Created.class.getSimpleName()).appendChild(wadsDoc.createTextNode(wads.getWadsHeader().getCreated())));
      wadsheader.appendChild(wadsDoc.createElement(Description.class.getSimpleName()).appendChild(wadsDoc.createTextNode(wads.getWadsHeader().getDescription())));
      
      Element archetype = wadsDoc.createElement(Archetype.class.getSimpleName());
      archetype.appendChild(wadsDoc.createTextNode(wads.getRequestDetails().getArchetype().toValue()));
      archetype.setAttribute("Id", wads.getRequestDetails().getArchetype().getId());
      archetype.setAttribute("Name", wads.getRequestDetails().getArchetype().getName());
      requestdetails.appendChild(archetype);
      
      requestdetails.appendChild(wadsDoc.createElement(CurrentActivity.class.getSimpleName()).appendChild(wadsDoc.createTextNode(wads.getRequestDetails().getCurrentActivity())));
      
      Element datafields = wadsDoc.createElement(DataFields.class.getSimpleName());
      for(int o=0;o<wads.getRequestDetails().getDataFields().size();o++) {
        Element datafield = wadsDoc.createElement(DataField.class.getSimpleName());
        datafield.setAttribute("Id", wads.getRequestDetails().getDataFields().getDataField(o+"").getId());
        datafield.setAttribute("Name", wads.getRequestDetails().getDataFields().getDataField(o+"").getName());
        datafield.appendChild(wadsDoc.createTextNode(wads.getRequestDetails().getDataFields().getDataField(o+"").toValue()));
        datafields.appendChild(datafield);
      }
      requestdetails.appendChild(datafields);
      
      for(int p=0;p<wads.getApprovals().size();p++) {
        Element approval = wadsDoc.createElement(Approval.class.getSimpleName());
        approval.appendChild(wadsDoc.createElement(ActivityId.class.getSimpleName()).appendChild(wadsDoc.createTextNode(wads.getApprovals().getApproval(p+"").getActivityId())));
        approval.appendChild(wadsDoc.createElement(Approver.class.getSimpleName()).appendChild(wadsDoc.createTextNode(wads.getApprovals().getApproval(p+"").getApprover())));
        approval.appendChild(wadsDoc.createElement(Created.class.getSimpleName()).appendChild(wadsDoc.createTextNode(wads.getApprovals().getApproval(p+"").getCreated())));
        approval.appendChild(wadsDoc.createElement(Replied.class.getSimpleName()).appendChild(wadsDoc.createTextNode(wads.getApprovals().getApproval(p+"").getReplied())));
        approval.appendChild(wadsDoc.createElement(Message.class.getSimpleName()).appendChild(wadsDoc.createTextNode(wads.getApprovals().getApproval(p+"").getMessage())));
        approvals.appendChild(approval);
      }
      
      //Write to file
      DOMSource source = new DOMSource(wadsDoc);
      Transformer trans = TransformerFactory.newInstance().newTransformer();
      trans.setOutputProperty("indent", "yes");
      trans.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2");
      trans.setOutputProperty("encoding", "utf-8");
      StreamResult fresult = new StreamResult(new OutputStreamWriter(new FileOutputStream(wadsfile, false), "UTF-8"));
      trans.transform(source, fresult);
    } catch (UnsupportedEncodingException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (TransformerException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (FileNotFoundException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ParserConfigurationException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    }
  }
  
  public org.enhydra.shark.xpdl.elements.Package readXPDL(String path) {
    JaWEManager.configure();
    JaWEManager mgr = JaWEManager.getInstance();
    mgr.init();
    org.enhydra.shark.xpdl.elements.Package pkg = mgr.getJaWEController().openPackageFromFile(path);
    pkg.setReadOnly(true);
    return pkg;
  }
  
  public org.enhydra.shark.xpdl.elements.Package readXPDL2(File f) {
    try {
      org.enhydra.shark.xpdl.elements.Package refPackage;
      Document document = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(f);
      Element packg = document.getDocumentElement();
      refPackage = new org.enhydra.shark.xpdl.elements.Package();
      
      if(packg.getNodeName().equals("Package")) {
        for(int i=0;i<packg.getChildNodes().getLength();i++) {
          if(packg.getChildNodes().item(i).getNodeName().equals("PackageHeader")) {
            PackageHeader refPH = new PackageHeader(refPackage);
            Node pheader = packg.getChildNodes().item(i);
            for(int j=0;j<pheader.getChildNodes().getLength();j++) {
              if(pheader.getChildNodes().item(j).getNodeName().equals("XPDLVersion")) {
                refPH.setXPDLVersion(pheader.getChildNodes().item(j).getNodeValue());
              }
              if(pheader.getChildNodes().item(j).getNodeName().equals("Created")) {
                refPH.setCreated(pheader.getChildNodes().item(j).getNodeValue());
              }
              if(pheader.getChildNodes().item(j).getNodeName().equals("Description")) {
                refPH.setDescription(pheader.getChildNodes().item(j).getNodeValue());
              }
              if(pheader.getChildNodes().item(j).getNodeName().equals("Vendor")) {
                refPH.setVendor(pheader.getChildNodes().item(j).getNodeValue());
              }
              if(pheader.getChildNodes().item(j).getNodeName().equals("Documentation")) {
                refPH.setDocumentation(pheader.getChildNodes().item(j).getNodeValue());
              }
            }
          }
          if(packg.getChildNodes().item(i).getNodeName().equals("WorkflowProcesses")) {
            WorkflowProcesses refWfs = new WorkflowProcesses(refPackage);
            Node wfs = packg.getChildNodes().item(i);
            for(int k=0;k<wfs.getChildNodes().getLength();k++) {
              
            }
          }
        }
      }
    } catch (SAXException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (IOException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    } catch (ParserConfigurationException ex) {
      Logger.getLogger(WADSUtil.class.getName()).log(Level.SEVERE, null, ex);
    }
    
    return null;
  }

}
